// // Copyright (c) 2009 All Right Reserved // // vl // // 2009-01-01 // Contains ... using LargoCommon.Interfaces; using System; using System.Collections; using System.Diagnostics.Contracts; using System.Globalization; using System.Text; using System.Xml.Serialization; namespace LargoCommon.Music { /// Rhythmical shape. /// Rhythmical shape represents simplified rhythm of one bar. It is always /// assigned to certain rhythmical modality (and to rhythmical GSystem). /// It has also inner characteristics (mobility, tension, ..). [Serializable] [XmlRoot] public class RhythmicShape : BinarySchema, IRhythmic, IModalStruct { //// Properties:mean, mobility, tension, jazz,entropy #region Constructors /// Initializes a new instance of the RhythmicShape class. Serializable. public RhythmicShape() { } /// /// Initializes a new instance of the RhythmicShape class. /// /// The given system. /// Bit array. public RhythmicShape(GeneralSystem givenSystem, BitArray bitArray) : base(givenSystem, bitArray) { Contract.Requires(givenSystem != null); } /// /// Initializes a new instance of the RhythmicShape class. /// /// The given system. /// Structural code. public RhythmicShape(GeneralSystem givenSystem, string structuralCode) : base(givenSystem, structuralCode) { Contract.Requires(givenSystem != null); } /// /// Initializes a new instance of the RhythmicShape class. /// /// Rhythmic shape. public RhythmicShape(BinaryStructure shape) : base(shape) { Contract.Requires(shape != null); } /// /// Initializes a new instance of the RhythmicShape class. /// /// System order. /// Rhythmical structure. public RhythmicShape(byte sysOrder, IGeneralStruct structure) : base(RhythmicSystem.GetRhythmicSystem(RhythmicDegree.Shape, sysOrder), (string)null) { Contract.Requires(structure != null); for (byte e = 0; e < this.GSystem.Order; e++) { if (structure.IsOn(e)) { this.On(e); } } this.DetermineLevel(); } /// /// Initializes a new instance of the RhythmicShape class. /// /// The given system. /// Number of structure. public RhythmicShape(GeneralSystem givenSystem, long number) : base(givenSystem, number) { } #endregion #region Interface /// Gets rhythmical system. /// Property description. [XmlIgnore] public RhythmicSystem RhythmicSystem => (RhythmicSystem)this.GSystem; /// Gets or sets rhythmical modality. /// Property description. [XmlIgnore] public RhythmicModality RhythmicModality { get; set; } /// Gets or sets previous rhythmical shape. /// Property description. [XmlIgnore] public RhythmicShape PreviousShape { get; set; } #endregion #region Static factory methods /// /// Get NewRhythmicShape. /// /// The given system. /// Structural code. /// /// Returns value. /// public static RhythmicShape GetNewRhythmicShape(GeneralSystem givenSystem, string structuralCode) { Contract.Requires(givenSystem != null); var rs = new RhythmicShape(givenSystem, structuralCode); rs.DetermineBehavior(); return rs; } /// /// Get NewRhythmicShape. /// /// The given system. /// Bit array. /// /// Returns value. /// public static RhythmicShape GetNewRhythmicShape(GeneralSystem givenSystem, BitArray bitArray) { Contract.Requires(givenSystem != null); var rs = new RhythmicShape(givenSystem, bitArray); rs.DetermineBehavior(); return rs; } /// /// Get New RhythmicShape. /// /// Rhythmic shape. /// Returns value. public static RhythmicShape GetNewRhythmicShape(BinaryStructure shape) { Contract.Requires(shape != null); var rs = new RhythmicShape(shape); rs.DetermineBehavior(); return rs; } /// /// Get NewRhythmicShape. /// /// Rhythmical Structure. /// Returns value. public static RhythmicShape GetNewRhythmicShape(FiguralStructure structure) { Contract.Requires(structure != null); var rs = new RhythmicShape(structure.GSystem.Order, structure); rs.DetermineBehavior(); return rs; } #endregion #region Public methods /// Makes a deep copy of the RhythmicShape object. /// Returns object. public override object Clone() { return GetNewRhythmicShape(this.GSystem, this.GetStructuralCode); } /// Validity test. /// Returns value. public override bool IsEmptyStruct() { return base.IsEmptyStruct() || this.IsOff(0); } /// Evaluate properties of the structure. public override void DetermineBehavior() { this.ComputeRhythmicProperties(); } #endregion #region Comparison /// Support sorting according to level and number. /// Object to be compared. /// Returns value. public override int CompareTo(object obj) { return obj is RhythmicShape rs ? string.Compare(this.ElementSchema, rs.ElementSchema, StringComparison.Ordinal) : 0; //// This kills the DataGrid //// throw new ArgumentException("Object is not a RhythmicShape"); } /// Test of equality. /// Object to be compared. /// Returns value. public override bool Equals(object obj) { //// check null (this pointer is never null in C# methods) if (object.ReferenceEquals(obj, null)) { return false; } if (object.ReferenceEquals(this, obj)) { return true; } if (this.GetType() != obj.GetType()) { return false; } return this.CompareTo(obj) == 0; } /// Support of comparison. /// Returns value. public override int GetHashCode() { return this.ElementSchema != null ? this.ElementSchema.GetHashCode() : 0; } #endregion #region String representation /// Returns value. /// List of figure elements. public override string ElementString() { var s = new StringBuilder(); for (byte e = 0; e < this.GSystem.Order; e++) { s.Append(this.IsOn(e) ? "V" : "-"); } return s.ToString(); } /// Short string representation of the object. /// Returns value. public string ToShortString() { var s = new StringBuilder(); s.Append(" " + this.ElementString()); s.Append(" " + this.DistanceSchema); return s.ToString(); } /// String representation of the object. /// Returns value. public override string ToString() { var s = new StringBuilder(); s.Append(string.Format(CultureInfo.InvariantCulture, "{0},{1}", base.ToString(), this.ElementString())); s.Append(","); s.AppendLine(this.StringOfProperties()); return s.ToString(); } #endregion } }